#include "VarDeclaration.h"
#include "../Exceptions.h"
#include "../GeneralVisitor.h"

VarDeclaration::VarDeclaration(string iVarName, TreeNode* iInitialValue)
{
    fVarName = iVarName;
    fInitialValue = iInitialValue;
}

VarDeclaration::~VarDeclaration()
{
    if(fInitialValue)
        delete fInitialValue;
}

void VarDeclaration::CheckVariables(set<string>& oVariables, string iParentName)
{
    if(oVariables.find(fVarName) != oVariables.end())
        throw DuplicateVarDeclarationException(iParentName, fVarName);

    if(fInitialValue != 0)
        fInitialValue->CheckVariables(oVariables, iParentName);

    // that's the magic :-)
    oVariables.insert(fVarName);
}

void VarDeclaration::CheckFunctionCalls(set<FunctionDefinition*>& iAllFunctions, string iParentName)
{
    if(fInitialValue != 0)
        fInitialValue->CheckFunctionCalls(iAllFunctions, iParentName);
}

void VarDeclaration::CheckClassConstructions(set<ClassDefinition*>& iAllClasses, string iParentName)
{
    if(fInitialValue != 0)
        fInitialValue->CheckClassConstructions(iAllClasses, iParentName);
}

void VarDeclaration::CheckExpressionTypes(map<string, ExpressionType*>& iVarTypes, string iParentName)
{
    // predpokladam, ze vsechny promenne uz budu mit deklarovane
    if(iVarTypes.find(this->fVarName) == iVarTypes.end())
        throw BaseException("VarDeclaration::CheckExpressionTypes: promenna uz v tuto chvili mela byt deklarovana!");
    else
        iVarTypes[this->fVarName]->UpdateValuesAndDiscardParam(new ExpressionType(Undefined, false));

    if(this->fInitialValue != 0)
    {
        ExpressionType* lType = this->fInitialValue->GetType(iVarTypes, iParentName);
        iVarTypes[this->fVarName]->UpdateValuesAndDiscardParam(lType);
    }
}

void VarDeclaration::Accept(GeneralVisitor* iVisitor)
{
    iVisitor->Visit(this);
}
